import { useEffect, useRef } from 'react'
import { PullToRefresh } from 'antd-mobile-v5'
import { useDispatch, useSelector } from 'react-redux'
import { usePersistFn } from 'ahooks'

import { getArticles, getMoreArticles } from '@/store/actions'

import MoreAction from '../MoreAction'
import ArticleItem from '@/components/ArticleItem'

import styles from './index.module.scss'
import { useHistory } from 'react-router'

// 该组件会接受到两个属性，分别是：
// channelId -> 频道的 id 值
// activeId -> 当前选中的频道 id 值
const ArticleList = ({ channelId, activeId }) => {
  const history = useHistory()
  // dispatch
  const dispatch = useDispatch()
  // 是否下拉刷新中的状态
  // 获取 redux 中的状态
  const { articles } = useSelector(state => state.home)
  // 用来表示加载中
  const isLoadingRef = useRef(false)
  // 创建页面滚动容器的ref
  const containerRef = useRef(null)
  // 创建文章列表底部的ref
  const bottomRef = useRef(null)

  // 根据当前频道id获取文章数据
  const channelArticle = articles[channelId] ?? {}
  const { prevTime, list } = channelArticle

  // 滚动事件处理程序
  const handleScroll = usePersistFn(async () => {
    const { bottom } = containerRef.current.getBoundingClientRect()
    const { top } = bottomRef.current.getBoundingClientRect()

    if (top - bottom <= 250) {
      if (channelId !== activeId) return
      if (!prevTime) return

      // 判断数据是否加载中
      if (isLoadingRef.current) return

      // 发请求拿数据
      isLoadingRef.current = true
      // 注意：该代码会发送请求是异步的，所以，此处需要 await 等到异步操作完成后，再修改标记！！！
      await dispatch(getMoreArticles(channelId, prevTime))
      isLoadingRef.current = false
    }
  })

  // 监听页面滚动
  useEffect(() => {
    const containerDOM = containerRef.current
    containerDOM.addEventListener('scroll', handleScroll)
    return () => {
      containerDOM.removeEventListener('scroll', handleScroll)
    }
  }, [handleScroll])

  useEffect(() => {
    // 注意：此处，只需要获取到当前选中的频道的文章列表数据即可，
    //      而没有选中的频道暂时没有必要获取他们的文章列表数据( 这些数据也是在选中时获取即可 )
    if (channelId !== activeId) return

    // 判断当前频道有没有文章列表数据
    if (list?.length > 0) return

    dispatch(getArticles(channelId, new Date()))
  }, [dispatch, channelId, activeId, list])

  // 下拉刷新文章列表
  const onRefresh = () => {
    dispatch(getArticles(channelId, new Date()))
  }

  // 渲染文章列表
  const renderArticleList = () => {
    // 如果没有列表数据，直接返回 null，表示不渲染任何内容
    if (!list) return null

    // 有数据，再渲染列表
    return list.map(item => {
      const {
        art_id,
        /* aut_id,*/ aut_name,
        comm_count,
        cover: { type, images },
        pubdate,
        title
      } = item

      const articleItemProps = {
        type,
        title,
        aut_name,
        comm_count,
        pubdate,
        images,
        isLogin: false
      }
      return (
        <div
          key={art_id}
          className="article-item"
          onClick={() => history.push(`/article/${art_id}`)}
        >
          {/* 文章列表中的每一项 */}
          <ArticleItem {...articleItemProps} />
        </div>
      )
    })
  }

  return (
    <div
      ref={containerRef}
      className={styles.root}
      style={{ display: activeId === channelId ? 'block' : 'none' }}
    >
      {/* 文章列表 */}
      <div className="articles">
        <PullToRefresh
          // 下拉刷新时触发的事件
          onRefresh={onRefresh}
        >
          {/* 渲染文章列表 */}
          {renderArticleList()}

          {/* 列表最底部的元素，用该元素来判断距离 */}
          <div className="infinite" ref={bottomRef} />
        </PullToRefresh>
      </div>

      {/* 举报 */}
      <MoreAction visible={false} />
    </div>
  )
}

export default ArticleList
